package com.mrzhou.study.struct.queue;

/**
 * 通过数组实现队列,
 *      队列一般有front(头部指针) 和 rear(尾部指针)
 *   以下代码是视频中的实现思路, 个人的实现思路见QueueAround.class
 */
public class ArrayQueue<T> {

    private Object[] queue; // 队列
    private int front ; // 头部指针
    private int rear ; // 尾部指针
    private int maxSize; // 队列的最大长度

    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize + 1;
        queue = new Object[this.maxSize + 1]; // 空出一个空余位置, 方便计算
    }

    public void add(T elem) {
        if(isFull()) { // 判断队列是否已满
            return;
        }
        queue[rear] = elem;
        rear = (rear + 1) % maxSize ;
    }

    public T poll() {
        if(isEmpty()) {
            return null;
        }
        T temp = (T) queue[front];
        front = (front + 1) % maxSize;
        return temp;
    }

    public static void main(String[] args) {
        ArrayQueue<String> queue = new ArrayQueue<>(2);
        int size = queue.size();
        queue.add("1");
        queue.add("2");
        System.out.println(queue.poll());
        queue.add("3");
    }

    public int size() {
        return (rear + maxSize -front) % maxSize; // 计算当前队列中的有效元素
    }


    /**
     * 队列的边界条件
     */
    public boolean isEmpty() {
        return rear == front; // 头部指针和尾部指针相同时, 队列为空
    }

    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("[");
        for (int i = front; i < front +size(); i++) {
            if(i == front + size() -1) {
                sb.append(queue[i % maxSize]);
            } else {
                sb.append(queue[i % maxSize]).append(",");
            }
        }
        return sb.append("]").toString();
    }

}
